package com.redteam.data.dao;

import com.redteam.data.beans.Person;
import com.redteam.data.dao.interfaces.DAO;
import java.sql.Statement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

/**
 * DAO for retrieving a <code>Person's</code> data
 *
 * @author Jezreel Wilson
 * @author Steven Lawton
 * @version 1.0
 */
public class PersonsDAO extends AbstractDAO implements DAO {

    private static PersonsDAO dao;
    private static DataSource ds;
    private final String tableName;

    static {
        dao = new PersonsDAO();
    }

    /**
     * Returns the instance of this DAO.
     *
     * @return Singleton instance for use
     */
    public static PersonsDAO getInstance() {
        return dao;
    }

    private PersonsDAO() {
        getDataSource();
        this.tableName = "HIGHFLIERS.PERSONS";
    }

    /**
     * (@inherentDoc)
     */
    @Override
    public DataSource getDS() {
        return PersonsDAO.ds;
    }

    private void getDataSource() {
        try {
            InitialContext ic = new InitialContext();
            ds = (DataSource) ic.lookup("jdbc/redteam");

        } catch (NamingException ex) {
            Logger.getLogger(PersonsDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * (@inherentDoc)
     */
    @Override
    public Person getObjectOut(ResultSet rs) throws SQLException {

        Person p = new Person();
        p.setId(rs.getLong("ID"));
        p.setFirstName(rs.getString("FIRSTNAME"));
        p.setMiddleName(rs.getString("MIDDLENAME"));
        p.setLastName(rs.getString("LASTNAME"));
        p.setStreet(rs.getString("STREET"));
        p.setCity(rs.getString("CITY"));
        p.setState(rs.getString("STATE"));
        p.setZipCode(rs.getString("ZIPCODE"));
        p.setEmail(rs.getString("EMAIL"));
        p.setfBOId(rs.getLong("FBO_ID"));
        p.setBirthDate(rs.getDate("BIRTHDATE"));
        p.setHomePhone(rs.getString("HOMEPHONE"));
        p.setCellPhone(rs.getString("CELLPHONE"));
        p.setWorkPhone(rs.getString("WORKPHONE"));
        p.setGender(rs.getString("GENDER"));
        p.setDiscriminator(rs.getString("DISCRIMINATOR"));
        p.setUsername(rs.getString("USER_NAME"));
        p.setPassword(rs.getString("PASSWORD"));

        return p;
    }

    /**
     * Returns the <code>Person</code> object identified by specified username
     *
     * @param username Username of the <code>Person</code>
     * @return <code>Person</code> object reference
     */
    public Person getSingle(String username) {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        Person p = null;
        try {
            conn = getDS().getConnection();
            st = conn.createStatement();
            StringBuilder sb = new StringBuilder("SELECT * FROM ").append(this.getTableName()).append(" WHERE USERNAME = '").append(username).append("'");
            rs = st.executeQuery(sb.toString());
            while (rs.next()) {
                p = this.getObjectOut(rs);
            }
        } catch (SQLException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            closeConnection(rs, st, conn);
            return p;
        }
        
    }

    /**
     * (@inherentDoc)
     */
    @Override
    public String buildInsertQuery(Object objectToInsert) {
        Person person = (Person) objectToInsert;
        StringBuilder sb = new StringBuilder();
        sb.append("INSERT INTO ").append(this.getTableName());
        sb.append(" (FIRSTNAME,MIDDLENAME,LASTNAME,STREET,CITY,STATE,ZIPCODE,EMAIL,FBO_ID,");
        sb.append("BIRTHDATE,HOMEPHONE,CELLPHONE,WORKPHONE,GENDER,DISCRIMINATOR,USER_NAME,PASSWORD)");
        sb.append(" VALUES ('");
        sb.append(person.getFirstName()).append("',' ");
        sb.append(person.getMiddleName()).append("','");
        sb.append(person.getLastName()).append("','");
        sb.append(person.getStreet()).append("','");
        sb.append(person.getCity()).append("','");
        sb.append(person.getState()).append("','");
        sb.append(person.getZipCode()).append("','");
        sb.append(person.getEmail()).append("',");
        sb.append(person.getfBOId()).append(",'");
        sb.append(person.getBirthDate()).append("','");
        sb.append(person.getHomePhone()).append("','");
        sb.append(person.getCellPhone()).append("','");
        sb.append(person.getWorkPhone()).append("','");
        sb.append(person.getGender()).append("','");
        sb.append(person.getDiscriminator()).append("','");
        sb.append(person.getUsername()).append("','");
        sb.append(person.getPassword()).append("')");

        return new String(sb);
    }

    /**
     * (@inherentDoc)
     */
    @Override
    public String buildUpdateQuery(Object objectToUpdate) {
        Person person = (Person) objectToUpdate;
        StringBuilder sb = new StringBuilder("UPDATE ");
        sb.append(this.getTableName()).append(" SET FIRSTNAME = '").append(person.getFirstName());
        sb.append("',MIDDLENAME='").append(person.getMiddleName());
        sb.append("',LASTNAME='").append(person.getLastName()).append("',STREET='");
        sb.append(person.getStreet()).append("',CITY='").append(person.getCity());
        sb.append("',STATE='").append(person.getState()).append("',ZIPCODE='");
        sb.append(person.getZipCode()).append("',EMAIL='").append(person.getEmail());
        sb.append("',FBO_ID=").append(person.getfBOId());
        sb.append(",BIRTHDATE='").append(person.getBirthDate());
        sb.append("',HOMEPHONE='").append(person.getHomePhone());
        sb.append("',CELLPHONE='").append(person.getCellPhone());
        sb.append("',WORKPHONE='").append(person.getWorkPhone());
        sb.append("',GENDER='").append(person.getGender());
        sb.append("',DISCRIMINATOR='").append(person.getDiscriminator());
        sb.append("',USER_NAME='").append(person.getUsername());
        sb.append("',PASSWORD='").append(person.getPassword());
        sb.append("' WHERE ID= ").append(person.getId());

        return sb.toString();
    }

    public String personDescriminator(long personId) {
        Person p = null;
        try {
            p = (Person) this.getSingle(personId);
        } catch (SQLException ex) {
            Logger.getLogger(PersonsDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return p.getDiscriminator();
    }

    /**
     * (@inherentDoc)
     */
    @Override
    public long getObjectId(Object obj) {
        Person person = (Person) obj;
        return person.getId();
    }

    /**
     * (@inherentDoc)
     */
    @Override
    public String getTableName() {
        return this.tableName;
    }
}
